﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using Abp.Collections.Extensions;
using Castle.Compatibility;

namespace Vecen.BangChuang.Helpers {
    /// <summary>
    /// 
    /// </summary>
    public static class CommonHelper {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static TypeConverter GetCustomTypeConverter(Type type) {
            if(type == typeof(List<int>)) {
                return new GenericListTypeConverter<int>();
            }
            if(type == typeof(List<decimal>)) {
                return new GenericListTypeConverter<decimal>();
            }
            if(type == typeof(List<string>)) {
                return new GenericListTypeConverter<string>();
            }

            return TypeDescriptor.GetConverter(type);
        }

        /// <summary>
        /// 将数据库中timespan转换成十六进制字符串
        /// </summary>
        /// <param name="btTsArray">从数据库中获取的timespan值</param>      
        /// <returns>timespan十六进制字符串</returns>
        public static string ConvertToTimeSpanString(byte[] btTsArray) {
            string strTimeSpan = "0x" + BitConverter.ToString(btTsArray).Replace("-", "");
            return strTimeSpan;
        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <returns></returns>
        public static object To(object value, Type destinationType) {
            return To(value, destinationType, CultureInfo.InvariantCulture);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="destinationType"></param>
        /// <param name="culture"></param>
        /// <returns></returns>
        public static object To(object value, Type destinationType, CultureInfo culture) {
            if(value != null) {
                var sourceType = value.GetType();

                TypeConverter destinationConverter = GetCustomTypeConverter(destinationType);
                TypeConverter sourceConverter = GetCustomTypeConverter(sourceType);

                if(destinationConverter != null && destinationConverter.CanConvertFrom(value.GetType())) {
                    return destinationConverter.ConvertFrom(null, culture, value);
                }
                if(sourceConverter != null && sourceConverter.CanConvertTo(destinationType)) {
                    return sourceConverter.ConvertTo(null, culture, value, destinationType);
                }
                if(destinationType.GetTypeInfo().IsEnum && value is int) {
                    return Enum.ToObject(destinationType, (int)value);
                }
                if(!destinationType.IsInstanceOfType(value)) {
                    return Convert.ChangeType(value, destinationType, culture);
                }
            }

            return value;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="value"></param>
        /// <returns></returns>
        public static T To<T>(object value) {
            return (T)To(value, typeof(T));
        }

        /// <summary>
        /// 获得枚举备注
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string Description(this Enum value) {
            var fieldInfo = value.GetType().GetField(value.ToString());
            if(fieldInfo == null) {
                return "";
            }
            var descriptionAttributes =
                fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false) as DescriptionAttribute[];

            if(descriptionAttributes == null)
                return string.Empty;
            return (descriptionAttributes.Length > 0) ? descriptionAttributes[0].Description : value.ToString();
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="enumObj"></param>
        public static Dictionary<int, string> EnumToArray(this Enum enumObj) {
            Dictionary<int, string> enumValues = new Dictionary<int, string>();
            Type enumType = enumObj.GetType();
            foreach(string memberName in Enum.GetNames(enumType)) {
                MemberInfo member = enumType.GetMember(memberName).Single();
                string memberDescription =
                    ((DescriptionAttribute)member.GetCustomAttribute(typeof(DescriptionAttribute))).Description;

                enumValues.Add((int)Enum.Parse(enumType, memberName), memberDescription);
            }

            return enumValues;
        }


        /// <summary>
        /// 获得Sha256算法结果
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetSha256(string source) {
            var sha = SHA256.Create();
            var bytes = Encoding.UTF8.GetBytes(source);
            var crypto = sha.ComputeHash(bytes);
            return crypto.Select(c => c.ToString("x2")).JoinAsString("");
        }

        /// <summary>
        /// 获得Sha256算法结果
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetSha1(string source)
        {
            var sha = SHA1.Create();
            var bytes = Encoding.UTF8.GetBytes(source);
            var crypto = sha.ComputeHash(bytes);
            return crypto.Select(c => c.ToString("x2")).JoinAsString("");
        }

        /// <summary>
        /// 获得Base64编码
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static string GetBase64(string source) {
            var bytes = Encoding.UTF8.GetBytes(source);

            return Convert.ToBase64String(bytes);
        }
    }
}